Minimizing Final Time (Jennings Problem)
Solve an optimal control problem with a minimal final time. Set up and solve the Jennings optimal control benchmark problem.
Problem Statement and Model
When solving differential equations over a variable time interval $[0,t_f]$, we can apply a time-scaling transformation to normalize the interval to$[0,1]$. This is achieved by introducing a final time parameter $t_f$. The Jennings optimal control problem divides derivatives by $t_f$. In practice, $t_f$ appears on the right hand side to avoid any divisions by 0.
\[\begin{gathered} \frac{\frac{dx}{dt}}{t_f} = f(x,u) \\ \frac{dx}{dt} = t_f f(x,u) \\ \end{gathered}\]
Our specific problem is defined as the following:
\[\begin{aligned} &&\min_{u(t),t_f} t_f \\ &&\text{s.t.} &&& \frac{dx_1}{dt}= t_f u, && t \in [0,1] \\ &&&&&\frac{dx_2}{dt} = t_f \cos(x_1(t)), && t \in [0,1] \\ &&&&&\frac{dx_3}{dt} = t_f \sin(x_1(t)), && t \in [0,1] \\ &&&&&x(0) = [\pi/2, 4, 0] \\ &&&&&x_2(t_f) = 0 \\ &&&&&x_3(t_f) = 0 \\ &&&&&-2 \leq u(t) \leq 2 \end{aligned}\]
Model Definition
First we must import $InfiniteOpt$ and other packages.
using InfiniteOpt, Ipopt, Plots;
Next we specify an array of initial conditions.
x0 = [π/2, 4, 0]; # x(0) for x1,x2,x3
We initialize the infinite model and opt to use the Ipopt solver
m = InfiniteModel(Ipopt.Optimizer);
Recall t is specified as $\ t \in [0,1]$:
@infinite_parameter(m, t in [0,1],num_supports= 100)
t
Now let's specify descision variables. Notice that $t_f$ is not a function of time and is a singular value.
@variable(m, x[1:3], Infinite(t))
@variable(m, -2 <= u <= 2, Infinite(t))
@variable(m, 0.1 <= tf);
Specifying the objective to minimize final time:
@objective(m, Min, tf);
Define the ODEs which serve as our system model.
@constraint(m, ∂(x[1],t) == tf*u)
@constraint(m, ∂(x[2],t) == tf*cos(x[1]))
@constraint(m, ∂(x[3],t) == tf*sin(x[1]));
Set our inital and final conditions.
@constraint(m, [i in 1:3], x[i](0) == x0[i])
@constraint(m, x[2](1) <=0)
@constraint(m, x[3](1) <= 1e-1);
Problem Solution
Optimize the model:
optimize!(m)
This is Ipopt version 3.14.4, running with linear solver MUMPS 5.4.1.
Number of nonzeros in equality constraint Jacobian...: 1794
Number of nonzeros in inequality constraint Jacobian.: 2
Number of nonzeros in Lagrangian Hessian.............: 700
Total number of variables............................: 701
variables with only lower bounds: 1
variables with lower and upper bounds: 100
variables with only upper bounds: 0
Total number of equality constraints.................: 600
Total number of inequality constraints...............: 2
inequality constraints with only lower bounds: 0
inequality constraints with lower and upper bounds: 0
inequality constraints with only upper bounds: 2
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
0 1.0999999e-01 4.00e+00 7.38e-03 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 1.0009999e-01 3.98e+00 2.15e+02 -1.0 4.00e+00 - 1.00e+00 4.78e-03h 1
2 1.0000218e-01 3.98e+00 1.31e+05 -1.0 4.16e+01 - 4.77e-02 7.77e-05h 1
3 1.0000001e-01 3.98e+00 1.32e+05 -1.0 1.41e+05 - 1.41e-05 1.39e-05h 1
4 1.0000001e-01 3.98e+00 1.07e+05 -1.0 2.60e+04 - 9.52e-05 5.36e-05h 1
5 1.0000001e-01 3.98e+00 2.07e+05 -1.0 1.43e+04 - 1.90e-04 2.73e-05h 1
6 1.0000000e-01 3.98e+00 4.50e+05 -1.0 1.27e+05 - 2.01e-05 8.64e-06h 1
7r 1.0000000e-01 3.98e+00 1.00e+03 0.6 0.00e+00 - 0.00e+00 4.78e-07R 2
8r 1.0014680e-01 4.05e+00 1.92e+03 0.6 6.02e+00 - 6.22e-01 3.69e-02f 1
9r 1.0062971e-01 3.58e+00 1.41e+03 0.6 5.18e+00 - 1.00e+00 2.61e-01f 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
10 1.0064745e-01 3.58e+00 3.90e+03 -1.0 3.99e+00 - 1.00e+00 2.60e-04h 1
11 1.0105387e-01 3.57e+00 6.14e+03 -1.0 8.03e+02 - 7.79e-04 4.93e-04h 1
12 1.0130844e-01 3.57e+00 2.30e+04 -1.0 3.32e+03 - 1.74e-04 4.12e-05h 1
13 1.0131275e-01 3.57e+00 2.13e+05 -1.0 1.09e+04 - 2.61e-04 3.20e-05h 1
14r 1.0131275e-01 3.57e+00 1.00e+03 0.6 0.00e+00 - 0.00e+00 4.88e-07R 5
15r 1.8100817e-01 3.50e+00 1.88e+03 0.6 4.36e+00 - 7.49e-01 5.12e-02f 1
16r 1.8669905e-01 2.33e+00 2.00e+02 0.6 2.29e+00 - 9.28e-01 7.89e-01f 1
17 1.8722777e-01 2.33e+00 1.68e+02 -1.0 3.81e+00 - 1.34e-01 8.11e-04h 1
18 1.8921350e-01 2.33e+00 2.25e+04 -1.0 1.06e+02 - 3.22e-02 2.37e-04h 1
19 1.9127731e-01 2.32e+00 3.87e+04 -1.0 4.33e+02 - 5.26e-03 3.02e-03h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
20 1.9146732e-01 2.32e+00 1.58e+05 -1.0 4.59e+03 - 6.15e-04 1.52e-04h 1
21 1.9156826e-01 2.32e+00 9.58e+05 -1.0 8.57e+03 - 3.77e-04 7.65e-05h 1
22r 1.9156826e-01 2.32e+00 1.00e+03 0.4 0.00e+00 - 0.00e+00 3.51e-07R 5
23r 2.1757015e-01 1.96e+00 7.32e+02 0.4 1.33e+00 - 9.92e-01 2.67e-01f 1
24 2.1787418e-01 1.96e+00 3.86e+02 -1.0 3.24e+00 - 7.15e-02 1.89e-04h 1
25 2.1823093e-01 1.96e+00 9.27e+05 -1.0 2.86e+01 - 1.05e-01 4.33e-05h 1
26 2.1826491e-01 1.96e+00 4.64e+06 -1.0 2.91e+04 - 1.14e-04 2.25e-05h 1
27r 2.1826491e-01 1.96e+00 1.00e+03 0.3 0.00e+00 - 0.00e+00 1.55e-07R 2
28r 2.6610697e-01 1.14e+00 4.55e+02 0.3 1.52e+00 - 9.91e-01 5.45e-01f 1
29r 3.2355056e-01 1.72e-01 3.40e+02 0.3 4.55e+00 - 5.90e-01 2.47e-01f 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
30r 5.9791076e-01 2.47e-01 8.36e+01 0.3 1.08e+00 0.0 1.00e+00 8.10e-01f 1
31r 1.5393156e+00 1.30e+00 3.41e+02 -0.4 4.27e+00 0.4 1.78e-01 4.06e-01f 1
32r 1.7522485e+00 3.94e-01 1.40e+02 -0.4 1.26e+00 0.9 8.91e-01 6.62e-01f 1
33r 3.0683175e+00 1.80e+00 2.06e+02 -0.4 4.88e+00 0.4 2.65e-01 5.12e-01f 1
34r 4.0829865e+00 1.84e+00 2.89e+02 -0.4 1.66e+01 -0.1 2.27e-02 1.02e-01f 1
35r 4.2796802e+00 1.60e+00 3.08e+02 -0.4 2.03e+00 0.3 9.01e-01 1.26e-01f 1
36r 4.3283517e+00 1.51e+00 3.80e+02 -0.4 6.28e+00 - 1.00e+00 5.78e-02f 1
37r 4.3814442e+00 1.08e+00 4.96e+02 -0.4 5.56e-01 - 1.00e+00 2.82e-01f 1
38r 4.4392851e+00 1.45e-02 8.75e+00 -0.4 4.17e-01 - 1.00e+00 1.00e+00f 1
39 4.6154499e+00 1.30e-02 2.29e-02 -1.0 2.45e-01 - 9.73e-01 1.00e+00f 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
40 4.4905204e+00 1.16e-02 2.94e-03 -1.7 3.27e-01 - 1.00e+00 1.00e+00h 1
41 4.3393561e+00 6.04e-02 1.38e-02 -3.8 9.67e-01 - 9.08e-01 9.34e-01h 1
42 4.2946439e+00 6.77e-02 8.52e-03 -3.8 1.80e+00 - 8.70e-01 1.00e+00h 1
43 4.2898253e+00 1.86e-02 1.26e-03 -3.8 2.46e+00 - 1.00e+00 1.00e+00h 1
44 4.2875206e+00 4.66e-03 1.80e-04 -3.8 2.82e+00 - 1.00e+00 1.00e+00h 1
45 4.2874424e+00 1.23e-04 3.37e-06 -3.8 6.32e-01 - 1.00e+00 1.00e+00h 1
46 4.2847486e+00 1.90e-03 3.96e-04 -5.7 1.13e+00 - 8.52e-01 1.00e+00h 1
47 4.2846175e+00 4.56e-04 2.07e-05 -5.7 1.34e+00 - 9.72e-01 1.00e+00h 1
48 4.2846039e+00 7.22e-05 5.56e-07 -5.7 6.40e-01 - 1.00e+00 1.00e+00h 1
49 4.2846034e+00 8.59e-07 6.40e-09 -5.7 5.87e-02 - 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
50 4.2845650e+00 6.11e-06 1.18e-06 -8.6 1.22e-01 - 9.77e-01 1.00e+00h 1
51 4.2845649e+00 1.55e-08 1.17e-10 -8.6 1.04e-02 - 1.00e+00 1.00e+00h 1
52 4.2845648e+00 7.53e-12 5.91e-14 -9.0 1.52e-04 - 1.00e+00 1.00e+00h 1
Number of Iterations....: 52
(scaled) (unscaled)
Objective...............: 4.2845648348476271e+00 4.2845648348476271e+00
Dual infeasibility......: 5.9111156714079624e-14 5.9111156714079624e-14
Constraint violation....: 7.5290884637979616e-12 7.5290884637979616e-12
Variable bound violation: 0.0000000000000000e+00 0.0000000000000000e+00
Complementarity.........: 9.0923652519966649e-10 9.0923652519966649e-10
Overall NLP error.......: 9.0923652519966649e-10 9.0923652519966649e-10
Number of objective function evaluations = 67
Number of objective gradient evaluations = 41
Number of equality constraint evaluations = 67
Number of inequality constraint evaluations = 67
Number of equality constraint Jacobian evaluations = 57
Number of inequality constraint Jacobian evaluations = 57
Number of Lagrangian Hessian evaluations = 52
Total seconds in IPOPT = 0.191
EXIT: Optimal Solution Found.
Extract the results. Notice that we multiply by $t_f$ to scale our time.
ts = value(t)*value(tf)
u_opt = value(u)
x1_opt = value(x[1])
x2_opt = value(x[2])
x3_opt = value(x[3]);
Plot the results
plot(ts, u_opt, label = "u(t)", linecolor = :black, linestyle = :dash)
plot!(ts, x1_opt, linecolor = :blue, linealpha = 0.4, label = "x1")
plot!(ts, x2_opt, linecolor = :green, linealpha = 0.4, label = "x2")
plot!(ts, x3_opt, linecolor = :red, linealpha = 0.4, label = "x3");
Maintenance Tests
These are here to ensure this example stays up to date.
using Test
@test termination_status(m) == MOI.LOCALLY_SOLVED
@test has_values(m)
@test u_opt isa Vector{<:Real}
@test x1_opt isa Vector{<:Real}
Test Passed
This page was generated using Literate.jl.